#ifndef USR_CANFD_H
#define USR_CANFD_H

#include "stm32g4xx_hal.h"
#include "fdcan.h"

#define CANFD_MAX_DATA_LEN 64  // 定义最大数据长度为 64 字节
#define CANFD_TX_QUEUE_SIZE 5  // 定义发送队列大小
#define CANFD_MAX_FILTERS 14   // 定义最大过滤器数量，根据实际情况调整

#define CANFD_FRAME_PERIOD_TYPE    0  // 周期报文类型
#define CANFD_FRAME_EVENT_TYPE     1  // 事件报文类型


// CAN 帧配置结构体
typedef struct {
    uint32_t can_id;         // CAN ID
    uint8_t data_length;     // 数据长度，范围 8 - 64
    uint8_t is_extended_id;  // 是否为扩展 ID，0 为标准 ID，1 为扩展 ID
    uint8_t frame_type;      // 报文类型，1 为周期报文，0 为事件报文
} CanFdConfig;

// 发送消息结构体
typedef struct {
    CanFdConfig config;
    uint8_t *pdata;
} CanFdTxMessage;

// 过滤器配置结构体
typedef struct {
    uint32_t *ids;           // CAN ID 数组指针
    uint8_t count;           // ID 数量
    uint8_t is_extended_id;  // 是否为扩展 ID
} CanFdFilterConfig;


// 将 FDCAN_DLC 枚举值转换为 数据长度
uint8_t get_length_from_dlc(uint8_t dlc);

/**
 * @brief 向发送队列添加 CAN 消息
 * @param config CAN 帧配置信息
 * @param data 要发送的数据指针
 * @return HAL_StatusTypeDef 添加状态
 */
HAL_StatusTypeDef canfd_add_tx_message(const CanFdConfig *config, uint8_t *data);

/**
 * @brief 发送队列中的下一条消息
 */
void canfd_send_next_message(void);

/* 
 * @brief 调用此接口向CANFD的TX FIFO添加发送数据，注意一次性只能添加3条报文，否者FIFO将会溢出
 * @param canid CAN 标识符
 * @param data 要发送的数据指针
 * @param len 数据长度
*/
void canfd_send_message(uint32_t canid, uint8_t *data, uint8_t len);

/**
 * @brief 注册 FDCAN 接收消息回调函数
 * @param config CAN 帧配置信息
 * @param callback 回调函数指针
 */
void canfd_register_receive_callback(void (*callback)(FDCAN_RxHeaderTypeDef *, uint8_t *)) ;

/**
 * @brief 配置 FDCAN 接收过滤器
 * @param filter_config 过滤器配置信息
 * @return HAL_StatusTypeDef 配置状态
 */
HAL_StatusTypeDef canfd_configure_filters(const CanFdFilterConfig *filter_config);

#endif /* USR_CANFD_H */
